home *** CD-ROM | disk | FTP | other *** search
- /* rsc_fix.cc Tue 23 Feb 1993 17:36:42 Warwick Allison
- * Converted to C++,
- * Propagated 'header' and 'offset' parameters to all functions.
- *
- * Based loosely on:
- * RSCFIX.C 09/16/86 Ric Clayton
- */
-
- #include <aesbind.h>
- #include "rsc_gobj.h"
-
- // Convert a RSC pseudopointer into a real pointer. Assumes "offset".
- #define NIL (-1)
- #define RSH(x) (long(x) == NIL ? 0 : ((typeof(x))(long(x)+offset)))
-
- // Two different types of position adjustment.
- //
- // Proportion for forms...
- //
- #define adj(xywh, siz, scale) \
- ((siz)*((xywh) & 0x00FF) + (((unsigned short)(xywh)) >> 8)*(siz)/(scale))
- //
- // Standard for menus...
- //
- #define adj_menu(xywh, siz, scale) \
- ((siz)*((xywh) & 0x00FF) + (((unsigned short)(xywh)) >> 8))
-
-
- static void map_tree(OBJECT* tree, int from, int last, int routine(OBJECT&))
- // From ProGEM...
- {
- /* Initialize to impossible value: */
- /* TAIL won't point to self! */
- /* Look until final node, or off */
- /* the end of tree */
- int tmp1=from;
-
- while (from != last && from != NIL) {
- /* Did we 'pop' into this node */
- /* for the second time? */
- if (tree[from].ob_tail != tmp1) {
- tmp1 = from; /* This is a new node */
- from = NIL;
-
- /* Apply operation, testing */
- /* for rejection of sub-tree */
- if (routine(tree[tmp1])) from = tree[tmp1].ob_head;
-
- /* Subtree path not taken, */
- /* so traverse right */
- if (from == NIL) from = tree[tmp1].ob_next;
- } else {
- /* Revisiting parent: */
- /* No operation, move right */
- tmp1 = from;
- from = tree[tmp1].ob_next;
- }
- }
- }
-
- void fix_string(char* text)
- // Strip trailing '@' characters from text.
- {
- int i=0;
- while (text[i]) i++;
- i--;
- while (i>=0 && text[i]=='@') text[i--]=0;
- }
-
- static void fix_trindex(RSHDR* header, long offset)
- {
- OBJECT** rs_trindex=(OBJECT**)(header->rsh_trindex+offset);
-
- int i;
-
- for (i = 0; i < header->rsh_ntree; i++) {
- rs_trindex[i] = RSH(rs_trindex[i]);
- }
- }
-
- static void fix_objects(RSHDR* header, long offset)
- {
- OBJECT* rs_object=(OBJECT*)(header->rsh_object+offset);
-
- int i;
-
- for (i = 0; i < header->rsh_nobs; i++) {
- // Mask off extended type
- switch (rs_object[i].ob_type&0xff) {
- case G_BOX:
- case G_IBOX:
- case G_BOXCHAR:
- case G_USERDEF:
- break;
- case G_STRING:
- case G_TITLE:
- case G_BUTTON:
- rs_object[i].ob_spec = RSH(rs_object[i].ob_spec);
- fix_string((char*)rs_object[i].ob_spec);
- break;
- default:
- // XXX Assume that ALL new object types have a pseudopointer
- // XXX to object-specific data.
- // XXX This is a weakspot in this rsrc_load() reimplementation.
- rs_object[i].ob_spec = RSH(rs_object[i].ob_spec);
- }
- }
- }
-
- // Global variables for the map_tree routines
- static int wchar,hchar,rscw,rsch;
- static int titlefound;
-
- static int findtitle(OBJECT& o)
- {
- if ((o.ob_type&0xff) == G_TITLE) {
- titlefound=1;
- return 0;
- } else
- return 1;
- }
-
- static int pos_menu(OBJECT& o)
- {
- o.ob_x = adj_menu(o.ob_x, wchar, rscw);
- o.ob_y = adj_menu(o.ob_y, hchar, rsch);
- o.ob_width = adj_menu(o.ob_width, wchar, rscw);
- o.ob_height = adj_menu(o.ob_height, hchar, rsch);
- return 1;
- }
-
- static int pos_form(OBJECT& o)
- {
- o.ob_x = adj(o.ob_x, wchar, rscw);
- o.ob_y = adj(o.ob_y, hchar, rsch);
- o.ob_width = adj(o.ob_width, wchar, rscw);
- o.ob_height = adj(o.ob_height, hchar, rsch);
- return 1;
- }
-
- static void pos_objects(RSHDR* header, long offset, int rscW, int rscH)
- {
- rscw=rscW;
- rsch=rscH;
-
- int i;
-
- graf_handle( &wchar, &hchar, &i, &i );
-
- OBJECT* tree;
-
- for (i=0; tree=(OBJECT*)rsc_gobj(header,offset,R_TREE,i); i++) {
- titlefound=0;
- map_tree(tree,0,-1,findtitle);
-
- if (titlefound)
- map_tree(tree,0,-1,pos_menu);
- else
- map_tree(tree,0,-1,pos_form);
- }
- }
-
- static void fix_tedinfo(RSHDR* header, long offset)
- {
- TEDINFO* rs_tedinfo=(TEDINFO*)(header->rsh_tedinfo+offset);
-
- int i;
-
- for (i = 0; i < header->rsh_nted; i++) {
- rs_tedinfo[i].te_ptext=RSH(rs_tedinfo[i].te_ptext);
- rs_tedinfo[i].te_ptmplt=RSH(rs_tedinfo[i].te_ptmplt);
- rs_tedinfo[i].te_pvalid=RSH(rs_tedinfo[i].te_pvalid);
- fix_string(rs_tedinfo[i].te_ptext);
- }
- }
-
- static void fix_frstr(RSHDR* header, long offset)
- {
- char** rs_frstr=(char**)(header->rsh_frstr+offset);
-
- int i;
-
- for (i = 0; i < header->rsh_nstring; i++) {
- rs_frstr[i]=RSH(rs_frstr[i]);
- fix_string(rs_frstr[i]);
- }
- }
-
- static void fix_iconblk(RSHDR* header, long offset)
- {
- #ifdef ICONBLK_PLUS_2_BUG
- // ICONBLKs in the RSC file are 2 bytes shorter than those defined in gemfast.h
- # define RSHiconblk(x) (*((ICONBLK*)(header->rsh_iconblk+offset+x*(sizeof(ICONBLK)-2))))
- #else
- // ICONBLKs are the right size now.
- # define RSHiconblk(x) (*((ICONBLK*)(header->rsh_iconblk+offset+x*(sizeof(ICONBLK)))))
- #endif
- int i;
-
- for (i = 0; i < header->rsh_nib; i++)
- {
- RSHiconblk(i).ib_pmask=RSH(RSHiconblk(i).ib_pmask);
- RSHiconblk(i).ib_pdata=RSH(RSHiconblk(i).ib_pdata);
- RSHiconblk(i).ib_ptext=RSH(RSHiconblk(i).ib_ptext);
- fix_string(RSHiconblk(i).ib_ptext);
- }
- }
-
- static void fix_bitblk(RSHDR* header, long offset)
- {
- BITBLK* rs_bitblk=(BITBLK*)(header->rsh_bitblk+offset);
-
- int i;
-
- for (i = 0; i < header->rsh_nbb; i++)
- rs_bitblk[i].bi_pdata=RSH(rs_bitblk[i].bi_pdata);
- }
-
- static void fix_frimg(RSHDR* header, long offset)
- {
- char** rs_frimg=(char**)(header->rsh_frimg+offset);
-
- int i;
-
- for (i = 0; i < header->rsh_nimages; i++)
- rs_frimg[i]=RSH(rs_frimg[i]);
- }
-
-
- /* this is the only 'exported' function in
- * this module.
- */
- void rsc_fix(RSHDR* header, long offset, int rscw, int rsch)
- {
- fix_trindex(header,offset);
- fix_objects(header,offset);
- fix_tedinfo(header,offset);
- fix_iconblk(header,offset);
- fix_bitblk(header,offset);
- fix_frstr(header,offset);
- fix_frimg(header,offset);
- pos_objects(header,offset,rscw,rsch);
- }
-
- #undef adj
- #undef adj_menu
-